package com.ego.item.service.impl;

import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ego.common.pojo.PageResult;
import com.ego.exception.enums.ExceptionEnum;
import com.ego.exception.exception.EgoException;
import com.ego.item.entity.*;
import com.ego.item.mapper.*;
import com.ego.item.service.GoodsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


@Service
@Slf4j
public class GoodsServiceImpl implements GoodsService {
    @Resource
    private BrandMapper brandMapper;
    @Resource
    private CategoryMapper categoryMapper;
    @Resource
    private SpuMapper spuMapper;
    @Resource
    private SpuDetailMapper spuDetailMapper;
    @Resource
    private SkuMapper skuMapper;
    @Resource
    private StockMapper stockMapper;
    @Resource
    private AmqpTemplate amqpTemplate;


    @Override
    @Transactional(readOnly = true)
    public PageResult<SpuBO> page(String key, Boolean saleable, Integer page, Integer rows) {
        //分页查询spu
        //1.先查询总记录数
        QueryWrapper<Spu> queryWrapper = new QueryWrapper<>();
        queryWrapper
                //模糊查询
                .like(StringUtils.isNotBlank(key),"title", key)
                //精确查询
                .eq(saleable != null, "saleable", saleable);
        Integer total = spuMapper.selectCount(queryWrapper);

        //2.分页查询
        List<SpuBO> spuBOList = spuMapper.selectPage(key,saleable,(page-1)*rows,rows);

        return new PageResult<>(Long.valueOf(total),spuBOList);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void save(SpuBO spuBo) {
        try {
            //1.保存spu
            spuBo.setValid(true);
            spuBo.setLastUpdateTime(new Date());
            spuBo.setCreateTime(spuBo.getCreateTime());
            spuBo.setSaleable(true);
            spuMapper.insert(spuBo);
            //2.保存spu_detail
            Long id = spuBo.getId();
            SpuDetail spuDetail = spuBo.getSpuDetail();
            spuDetail.setSpuId(id);
            spuDetailMapper.insert(spuDetail);
            //3.保存所有sku以及对应库存
            List<Sku> skus = spuBo.getSkus();
            for (Sku sku : skus) {
                sku.setCreateTime(new Date());
                sku.setLastUpdateTime(new Date());
                //维护关系
                sku.setSpuId(spuBo.getId());
                skuMapper.insert(sku);
                //库存
                Stock stock = sku.getStock();
                stock.setSkuId(sku.getId());
                stockMapper.insert(stock);

                sendMessage(spuBo.getId(),"insert");
            }
        } catch (Exception e) {
            EgoException.error(log, ExceptionEnum.GOODS_SAVE_ERROR, e);
        }
    }

    @Override
    @Transactional(readOnly = true)
    public SpuDetail findSpuDetailById(Long spuId) {
        SpuDetail spuDetail = spuDetailMapper.selectById(spuId);
        if (spuDetail == null) {
            throw new EgoException(ExceptionEnum.SPEC_PARAM_NOT_FOUND);
        }
        return spuDetail;
    }

    @Override
    @Transactional(readOnly = true)
    public List<Sku> querySkuBySpuId(Long spuId) {
        List<Sku> skus = null;
        try {
            // 查询sku
            Map<String, Object> map = new HashMap<>(1);
            map.put("spu_id", spuId);
            skus = this.skuMapper.selectByMap(map);
            for (Sku sku : skus) {
                // 同时查询出库存
                sku.setStock(this.stockMapper.selectById(sku.getId()));
            }
            return skus;
        } catch (Exception e) {
            EgoException.error(log, ExceptionEnum.SKU_NOT_FOUND, e);
        }
        return skus;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SpuBO spuBo) {
        try {
            List<Sku> skus = this.querySkuBySpuId(spuBo.getId());
            if (!CollectionUtils.isEmpty(skus)) {
                List<Long> skuIdList = skus.stream().map(s -> s.getId()).collect(Collectors.toList());
                // 删除以前库存
                this.stockMapper.deleteBatchIds(skuIdList);

                // 删除以前的sku
                this.skuMapper.deleteBatchIds(skuIdList);

            }
            //3.保存所有sku以及对应库存
            List<Sku> skus1 = spuBo.getSkus();
            for (Sku sku : skus1) {
                sku.setCreateTime(new Date());
                sku.setLastUpdateTime(new Date());
                //维护关系
                sku.setSpuId(spuBo.getId());
                skuMapper.insert(sku);
                //库存
                Stock stock = sku.getStock();
                stock.setSkuId(sku.getId());
                stockMapper.insert(stock);
                // 更新spu
                spuBo.setLastUpdateTime(new Date());
                this.spuMapper.updateById(spuBo);
                // 更新spu详情
                this.spuDetailMapper.updateById(spuBo.getSpuDetail());
                sendMessage(spuBo.getId(),"update");
            }
        } catch (Exception e) {
            EgoException.error(log, ExceptionEnum.SKU_NOT_FOUND, e);
        }
    }

    @Override
    @Transactional(rollbackFor = EgoException.class)
    public void deleteSpuById(Long id) {
        try {
            Spu spu = new SpuBO();
            spu.setId(id);
            //状态设置为"已删除"
            spu.setValid(false);
            spuMapper.updateById(spu);
        } catch (Exception e) {
            log.error("删除商品异常", e);
            throw new EgoException(ExceptionEnum.DELETE_GOODS_ERROR);
        }
    }

    @Override
    @Transactional(rollbackFor = EgoException.class)
    public void updateShelf(Long id) {
        try {
            Spu spu = spuMapper.selectById(id);
            spu.setSaleable(!spu.getSaleable());
            spuMapper.updateById(spu);
        } catch (Exception e) {
            log.error("更改商品状态异常", e);
            throw new EgoException(ExceptionEnum.DELETE_GOODS_ERROR);
        }
    }

    @Override
    @Transactional(readOnly = true)
    public PageResult<SpuBO> goodsPage(Boolean saleable, Integer page, Integer rows) {
        PageResult<SpuBO> result = new PageResult<>();
        try {
            //查询总记录数
            Integer total = spuMapper.selectCount(
                    new QueryWrapper<Spu>()
                            .eq(saleable != null, "saleable", saleable)
            );
            result.setTotal(Long.valueOf(total));
            List<SpuBO> items = spuMapper.selectPageForES(saleable, (page - 1) * rows, rows);
            result.setItems(items);
        } catch (Exception e) {
            EgoException.error(log, ExceptionEnum.GOODS_PAGE_ERROR, e);
        }
        return result;

    }

    @Override
    public void sendMessage(Long id, String type) {
        // 发送消息
        try {
            this.amqpTemplate.convertAndSend("item." + type, id);
        } catch (Exception e) {
            log.error("{}商品消息发送异常，商品id：{}", type, id, e);
        }
    }

    @Override
    public SpuBO queryGoodsById(Long id) {
        /**
         * 第一页所需信息如下：
         * 1.商品的分类信息、所属品牌、商品标题、商品卖点（子标题）
         * 2.商品的包装清单、售后服务
         */
        Spu spu=this.spuMapper.selectById(id);
        SpuDetail spuDetail = this.spuDetailMapper.selectById(spu.getId());


        QueryWrapper<Sku> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("spu_id", spu.getId());
        List<Sku> skuList = this.skuMapper.selectList(queryWrapper);

        List<Long> skuIdList = new ArrayList<>();
        for (Sku sku : skuList){
            skuIdList.add(sku.getId());
        }

        List<Stock> stocks = this.stockMapper.selectBatchIds(skuIdList);

        for (Sku sku:skuList){
            for (Stock stock : stocks){
                if (sku.getId().equals(stock.getSkuId())){
                    sku.setStock(stock);
                }
            }
        }
        return SpuBO.builder()
                .id(spu.getId())
                .brandId(spu.getBrandId())
                .cid1(spu.getCid1())
                .cid2(spu.getCid2())
                .cid3(spu.getCid3())
                .brandId(spu.getBrandId())
                .title(spu.getTitle())
                .subTitle(spu.getSubTitle())
                .saleable(spu.getSaleable())
                .valid(spu.getValid())
                .createTime(spu.getCreateTime())
                .lastUpdateTime(spu.getLastUpdateTime())
                .skus(skuList)
                .spuDetail(spuDetail).build();
    }

    @Override
    public Sku findSkuBySkuId(Long skuId) {
        return skuMapper.selectById(skuId);
    }

    @Override
    public List<Sku> findSkuListBySkuIds(List<Long> skuIdList) {
        return skuMapper.selectBatchIds(skuIdList);
    }

    @Override
    public Boolean reduceStock(List<Map<Object, Object>> orderDetailList) {
        Boolean result = true;
        for (int i = 0; i < orderDetailList.size(); i++) {
            Map<Object, Object> orderDetail = orderDetailList.get(i);
            Object skuId = orderDetail.get("skuId");
            String s = skuId.toString();
            Long integer = Long.valueOf(s);
            Object num = orderDetail.get("num");
            String s1 = num.toString();
            Integer integer1 = Integer.valueOf(s1);

           /* Integer skuId = (Integer) orderDetail.get("skuId");
            Integer num = (Integer) orderDetail.get("num");*/
            //先加锁
            stockMapper.lockStock(integer);
            //减库存
            int count = stockMapper.reduceStock(integer,integer1);
            if (count == 0) {
                result = false;
                break;
            }
        }
        return result;
    }
}
